package com.yigo.framework.snapshot;

import org.mapstruct.AfterMapping;
import org.mapstruct.MappingTarget;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author chenzl
 */
public interface SnapshotConverter {
    /**
     * 不清空的属性
     */
    List<String> IGNORE_FIELDS = Arrays.asList("snapshot", "id", "version");

    @AfterMapping
    default void after(Object source, @MappingTarget Object target) {
        if (source instanceof DmoSnapshot && target instanceof PoSnapshot) {
            //领域层往持久层转换
            Object snapshot = ((DmoSnapshot) source).getSnapshot();
            ((PoSnapshot) target).setSnapshot(snapshot);
            //清空PO对象上没有改变的字段，mybatis对于空值不会持久化
            cleanPO((PoSnapshot) target);
        } else if (source instanceof PoSnapshot && target instanceof DmoSnapshot) {
            //持久层往领域层转换
            ((DmoSnapshot) target).setSnapshot(source);
        }
    }

    default void cleanPO(PoSnapshot target) {
        Object snapshot = target.getSnapshot();
        if (null == snapshot) {
            return;
        }
        Class<?> clazz = target.getClass();
        while (null != clazz) {
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                String fieldName = field.getName();
                if (IGNORE_FIELDS.contains(fieldName)) {
                    continue;
                }
                field.setAccessible(true);
                try {
                    Object newValue = field.get(target);
                    Object oldValue = field.get(snapshot);
                    if (Objects.equals(newValue, oldValue)) {
                        field.set(target, null);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            clazz = clazz.getSuperclass();
        }
    }
}
